﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Krist_em_up.Plateforms;

namespace Krist_em_up.Characters
{
    public abstract class Character : Sprite
    {

        protected bool isOnGround;
        public bool reachEnd;
        protected int previousBottom;
        protected Vector2 prevPosition;

        protected Vector2 beforeJump = Vector2.Zero;
        protected enum State
        {
            Jumping,
            Walking,
            Idle
        }
        protected State currentState;

        public Character(Kristemup agame, Vector2 position)
        {
            game = agame;
            this.position = position;
            beforeJump = position;
            direction = new Vector2(0, 0);
            currentState = State.Walking;
        }

        public void turnLeft()
        {
            if (currentState != State.Jumping)
                currentState = State.Walking;
            direction.X = -1;
        }
        public void turnRight()
        {
            if (currentState != State.Jumping)
                currentState = State.Walking;
            direction.X = 1;
        }
        public void Jump()
        {

            if (currentState != State.Jumping)
            {
                speed.Y = 8;
                direction.Y = -1;
                currentState = State.Jumping;
            }
        }
        public void Fall()
        {
            direction.Y = 1;
        }
        public void stop()
        {
            direction.X = 0;
            //direction.Y = 0;
        }
        public new void Update()
        {
            if (currentState == State.Jumping)
            {
                speed.Y -= 0.1f;
            }
            else
            {
                beforeJump = position;
            }
            base.Update();
        }
        public new void Draw(SpriteBatch spriteBatch)
        {
        }
        public  abstract void UpdateRectangle();

        /// <summary>
        /// Handle collisions with tiles around our little KRIS
        /// </summary>
        protected void HandleCollisions()
        {
            // Get the player's bounding rectangle and find neighboring tiles.
            Rectangle bounds = rectangle;
            int leftTile = (int)Math.Floor((float)bounds.Left / Plateform.Width);
            int rightTile = (int)Math.Ceiling(((float)bounds.Right / Plateform.Width));
            int topTile = (int)Math.Floor((float)bounds.Top / Plateform.Height);
            int bottomTile = (int)Math.Ceiling(((float)bounds.Bottom / Plateform.Height));

            // Reset flag to search for ground collision.
            isOnGround = false;

            // For each potentially colliding tile,
            for (int y = topTile; y <= bottomTile; ++y)
            {
                for (int x = leftTile; x <= rightTile; ++x)
                {
                    // If this tile is collidable,
                    if (game.map.Plateforms.GetLength(0) > x && game.map.Plateforms.GetLength(1) > y && y >= 0 && x >= 0)
                    {
                        TileCollision collision = game.map.Plateforms[x, y].Collision;
                        if (collision == TileCollision.Impassable)
                        {
                            Rectangle tileBounds = Plateform.GetBounds(x, y);
                            Vector2 depth = RectangleExtensions.GetIntersectionDepth(bounds, tileBounds);
                            if (depth != Vector2.Zero)
                            {
                                float absDepthX = Math.Abs(depth.X);
                                float absDepthY = Math.Abs(depth.Y);

                                // Resolve the collision along the shallow axis.
                                if (absDepthY < absDepthX)
                                {
                                    // If we crossed the top of a tile, we are on the ground.
                                    if (previousBottom <= tileBounds.Top)
                                    {
                                        isOnGround = true;
                                    }

                                    position.Y = position.Y + depth.Y;
                                    UpdateRectangle();
                                    bounds = rectangle;
                                }
                                else
                                {
                                    // Resolve the collision along the X axis.
                                    position.X = position.X + depth.X;

                                    // Perform further collisions with the new bounds.
                                    UpdateRectangle();
                                    bounds = rectangle;
                                }
                            }
                        }
                        else if (collision == TileCollision.EndOfLevel)
                        {
                            reachEnd = true;
                        }
                    }
                }
            }
            // Save the new bounds bottom.
            previousBottom = bounds.Bottom;
        }

        /// <summary>
        /// Damn! That shit hurts
        /// </summary>
        /// <param name="amount">Amount of damage dealt to the character</param>
        //public virtual void Damage(int amount)
        //{

        //}
    }
}